from rest_framework import viewsets, status, serializers
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
from apps.common.permissions import SelfReadPermission, SelfUpdatePermission
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from drf_spectacular.utils import extend_schema_view, extend_schema, OpenApiParameter
from drf_spectacular.types import OpenApiTypes
from django.utils import timezone

from apps.common.responses import ApiResponseMixin, create_success_response_serializer
from apps.common.responses import ValidationErrorResponseSerializer, UnauthorizedErrorResponseSerializer, NotFoundErrorResponseSerializer

 
from .models import User
from .serializers import (
    UserSerializer, UserRegistrationSerializer, UserLoginSerializer,
    UserProfileSerializer, UserPasswordChangeSerializer, UserTokenSerializer,
    TokenObtainPairSerializer, UserPasswordResetSerializer,
    UserPermissionExtensionSerializer, UserSetPermissionsSerializer,
    UserPermissionOperationResultSerializer
)
from django.contrib.auth.models import Permission
from apps.permissions.models import PermissionExtension, UserRoleAssignment
from django.utils import timezone
from django.db import models


 
@extend_schema_view(
    list=extend_schema(
        summary="获取用户列表",
        description="获取用户列表，支持分页、搜索和过滤",
        parameters=[
            OpenApiParameter(name='status', type=OpenApiTypes.STR, description='用户状态过滤'),
            OpenApiParameter(name='search', type=OpenApiTypes.STR, description='搜索用户名或邮箱'),
        ],
    ),
    retrieve=extend_schema(
        summary="获取用户详情",
        responses={
            200: create_success_response_serializer(UserProfileSerializer, "获取成功", "Retrieve"),
        }
    ),
    create=extend_schema(
        summary="创建用户",
        responses={
            201: create_success_response_serializer(UserProfileSerializer, "创建成功", "Create"),
            400: ValidationErrorResponseSerializer,
        }
    ),
    update=extend_schema(
        summary="更新用户信息",
        responses={
            200: create_success_response_serializer(UserProfileSerializer, "更新成功", "Update"),
            400: ValidationErrorResponseSerializer,
        }
    ),
    destroy=extend_schema(
        summary="删除用户",
        responses={
            204: None,
        }
    ),
)
class UserViewSet(ApiResponseMixin, viewsets.ModelViewSet):
    """用户管理ViewSet"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
    search_fields = ['username', 'email', 'real_name']
    filterset_fields = ['status', 'is_active', 'is_staff']
    ordering_fields = ['username', 'created_at', 'last_login_at']
    ordering = ['-created_at']
    
    def get_permissions(self):
        """根据action设置权限"""
        if self.action in ['register', 'login']:
            # 注册和登录不需要权限
            return [AllowAny()]
        else:
            # 所有其他操作使用全局配置的权限类（ExtendedModelPermissions）
            return super().get_permissions()
    
    def get_serializer_class(self):
        """根据action返回不同的序列化器"""
        if self.action == 'register':
            return UserRegistrationSerializer
        elif self.action == 'login':
            return UserLoginSerializer
        elif self.action == 'profile':
            return UserProfileSerializer
        elif self.action == 'change_password':
            return UserPasswordChangeSerializer
        elif self.action == 'reset_password':
            return UserPasswordResetSerializer
        return super().get_serializer_class()

    @extend_schema(
        summary="用户注册",
        request=UserRegistrationSerializer,
        responses={
            201: create_success_response_serializer(UserTokenSerializer, "注册成功", "Register"),
            400: ValidationErrorResponseSerializer,
        }
    )
    @action(detail=False, methods=['post'], permission_classes=[AllowAny])
    def register(self, request):
        """用户注册"""
        serializer = self.get_serializer(data=request.data)
        
        if not serializer.is_valid():
            return self.error_response("注册信息无效", errors=serializer.errors, code=400)
        
        user = serializer.save()
        
        # 生成JWT Token
        refresh = RefreshToken.for_user(user)
        
        return self.success_response({
            'access': str(refresh.access_token),
            'refresh': str(refresh),
            'user': UserProfileSerializer(user).data
        }, "注册成功", code=201)

    @extend_schema(
        summary="用户登录",
        request=UserLoginSerializer,
        responses={
            200: create_success_response_serializer(UserTokenSerializer, "登录成功", "Login"),
            401: UnauthorizedErrorResponseSerializer,
        }
    )
    @action(detail=False, methods=['post'], permission_classes=[AllowAny])
    def login(self, request):
        """用户登录"""
        serializer = self.get_serializer(data=request.data)
        
        if not serializer.is_valid():
            return self.error_response("登录信息无效", errors=serializer.errors, code=401)
        
        user = serializer.validated_data['user']
        
        # 更新最后登录时间
        user.last_login_at = timezone.now()
        user.save(update_fields=['last_login_at'])
        
        # 生成JWT Token
        refresh = RefreshToken.for_user(user)
        
        return self.success_response({
            'access': str(refresh.access_token),
            'refresh': str(refresh),
            'user': UserProfileSerializer(user).data
        }, "登录成功")

    @extend_schema(
        summary="获取个人信息",
        request=None,
        responses={
            200: create_success_response_serializer(UserProfileSerializer, "获取成功", "Profile"),
        }
    )
    @action(detail=False, methods=['get'])
    def profile(self, request):
        """获取当前用户个人信息"""
        serializer = self.get_serializer(request.user)
        return self.success_response(serializer.data, "获取个人信息成功")

    @extend_schema(
        summary="更新个人信息",
        request=UserProfileSerializer,
        responses={
            200: create_success_response_serializer(UserProfileSerializer, "更新成功", "ProfileUpdate"),
            400: ValidationErrorResponseSerializer,
        }
    )
    @action(detail=False, methods=['put', 'patch'])
    def update_profile(self, request):
        """更新当前用户个人信息"""
        serializer = self.get_serializer(request.user, data=request.data, partial=True)
        
        if not serializer.is_valid():
            return self.error_response("更新信息无效", errors=serializer.errors, code=400)
        
        user = serializer.save()
        return self.success_response(
            UserProfileSerializer(user).data, 
            "个人信息更新成功"
        )

    @extend_schema(
        summary="修改密码",
        request=UserPasswordChangeSerializer,
        responses={
            200: create_success_response_serializer(UserProfileSerializer, "密码修改成功", "PasswordChange"),
            400: ValidationErrorResponseSerializer,
        }
    )
    @action(detail=False, methods=['post'])
    def change_password(self, request):
        """修改当前用户密码"""
        serializer = self.get_serializer(data=request.data, context={'request': request})
        
        if not serializer.is_valid():
            return self.error_response("密码信息无效", errors=serializer.errors, code=400)
        
        user = serializer.save()
        return self.success_response(
            UserProfileSerializer(user).data,
            "密码修改成功"
        )

    @extend_schema(
        summary="重置用户密码",
        description="管理员重置指定用户的密码，可以自动生成或指定新密码",
        request=UserPasswordResetSerializer,
        responses={
            200: create_success_response_serializer(UserProfileSerializer, "密码重置成功", "PasswordReset"),
            400: ValidationErrorResponseSerializer,
            404: "用户不存在",
        }
    )
    @action(detail=True, methods=['post'], permission_classes=[SelfUpdatePermission])
    def reset_password(self, request, pk=None):
        """重置指定用户密码（管理员功能）"""
        try:
            user = self.get_object()
        except User.DoesNotExist:
            return self.error_response("用户不存在", code=404)

        # 检查权限：只有管理员或超级用户可以重置密码
        if not (request.user.is_staff or request.user.is_superuser):
            return self.error_response("权限不足，只有管理员可以重置用户密码", code=403)

        # 不能重置自己的密码（防止意外锁定）
        if user == request.user:
            return self.error_response("不能重置自己的密码，请使用修改密码功能", code=400)

        serializer = self.get_serializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("重置密码信息无效", errors=serializer.errors, code=400)

        # 执行密码重置
        result = serializer.save(user)

        # 返回结果（包含新密码）
        response_data = {
            'user': UserProfileSerializer(result['user']).data,
            'new_password': result['new_password'],
            'auto_generated': result['auto_generated']
        }

        message = f"用户 {user.username} 的密码已重置"
        if result['auto_generated']:
            message += "，新密码已自动生成"

        return self.success_response(response_data, message)

    @extend_schema(
        summary="获取当前用户权限",
        description="获取当前用户的所有权限列表",
        request=None,
        responses={
            200: create_success_response_serializer(UserPermissionExtensionSerializer(many=True), "获取成功", "CurrentUserPermissions"),
        }
    )
    @action(detail=False, methods=['get'])
    def permissions(self, request):
        """获取当前用户权限 - 模式3A: 自定义Action"""
        user = request.user

        # 获取用户直接分配的权限ID
        user_permission_ids = user.user_permissions.values_list('id', flat=True)
        # 获取通过组获得的权限ID
        group_permission_ids = Permission.objects.filter(group__user=user).values_list('id', flat=True)

        # 合并权限ID并去重
        all_permission_ids = set(user_permission_ids) | set(group_permission_ids)

        # 获取对应的权限扩展对象
        permission_extensions = PermissionExtension.objects.filter(
            permission_id__in=all_permission_ids,
            status='active'
        ).order_by('module', 'permission__name')

        # 使用序列化器序列化数据
        serializer = UserPermissionExtensionSerializer(permission_extensions, many=True)
        return self.success_response(serializer.data, "权限列表获取成功")

    @extend_schema(
        summary="获取当前用户角色",
        description="获取当前用户的所有角色列表",
        request=None,
        responses={
            200: create_success_response_serializer(serializers.ListSerializer(child=serializers.CharField()), "获取成功", "CurrentUserRoles"),
        }
    )
    @action(detail=False, methods=['get'])
    def roles(self, request):
        """获取当前用户角色 - 模式3A: 自定义Action"""
        try:
            from apps.common.decorators import get_user_roles
            roles = get_user_roles(request.user)
            role_codes = [role.code for role in roles if hasattr(role, 'code')]
            return self.success_response(role_codes, "角色列表获取成功")
        except Exception as e:
            return self.error_response(f"获取角色失败: {str(e)}", code=500)

    @extend_schema(
        summary="获取用户权限",
        description="获取指定用户的权限列表",
        request=None,
        responses={
            200: create_success_response_serializer(UserPermissionExtensionSerializer(many=True), "获取成功", "UserPermissions"),
            404: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=True, methods=['get'], permission_classes=[SelfReadPermission])
    def user_permissions(self, request, pk=None):
        """获取用户权限 - 模式3A: 自定义Action"""
        user = self.get_object()

        # 获取用户直接分配的权限ID
        user_permission_ids = user.user_permissions.values_list('id', flat=True)
        # 获取通过组获得的权限ID
        group_permission_ids = Permission.objects.filter(group__user=user).values_list('id', flat=True)

        # 合并权限ID并去重
        all_permission_ids = set(user_permission_ids) | set(group_permission_ids)

        # 获取对应的权限扩展对象
        permission_extensions = PermissionExtension.objects.filter(
            permission_id__in=all_permission_ids,
            status='active'
        ).order_by('module', 'permission__name')

        # 使用序列化器序列化数据
        serializer = UserPermissionExtensionSerializer(permission_extensions, many=True)
        return self.success_response(serializer.data, "用户权限获取成功")

    @extend_schema(
        summary="设置用户权限",
        description="为用户设置直接权限",
        request=UserSetPermissionsSerializer,
        responses={
            200: create_success_response_serializer(UserPermissionOperationResultSerializer, "设置成功", "SetPermissions"),
            400: ValidationErrorResponseSerializer,
            404: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=True, methods=['post'], permission_classes=[SelfUpdatePermission])
    def set_permissions(self, request, pk=None):
        """设置用户权限 - 模式3A: 自定义Action"""
        user = self.get_object()

        # 使用序列化器验证请求数据
        serializer = UserSetPermissionsSerializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("请求参数无效", errors=serializer.errors, code=400)

        permission_extension_ids = serializer.validated_data['permission_extension_ids']

        # 获取有效的权限扩展
        permission_extensions = PermissionExtension.objects.filter(
            id__in=permission_extension_ids,
            status='active'
        )

        # 获取对应的Django权限
        django_permissions = [ext.permission for ext in permission_extensions]

        # 设置用户权限
        user.user_permissions.set(django_permissions)

        # 清理权限相关缓存
        self._clear_user_permission_cache(user)

        # 返回操作结果
        result_data = {
            'count': len(django_permissions),
            'message': f"成功为用户设置{len(django_permissions)}个权限"
        }
        result_serializer = UserPermissionOperationResultSerializer(result_data)
        return self.success_response(result_serializer.data, "用户权限设置成功")

    def _clear_user_permission_cache(self, user):
        """清理用户权限相关缓存"""
        from django.core.cache import cache

        # 1. 清理Django内置的用户权限缓存
        if hasattr(user, '_perm_cache'):
            delattr(user, '_perm_cache')
        if hasattr(user, '_user_perm_cache'):
            delattr(user, '_user_perm_cache')
        if hasattr(user, '_group_perm_cache'):
            delattr(user, '_group_perm_cache')

        # 2. 清理自定义权限缓存
        cache_key = f'user_permissions:{user.id}'
        cache.delete(cache_key)

        # 3. 清理其他相关缓存
        cache.delete_many([
            f'user_roles:{user.id}',
            f'user_profile:{user.id}',
        ])

 
    @extend_schema(
        summary="获取所有可分配权限",
        description="获取所有可分配的权限扩展列表",
        request=None,
        responses={
            200: create_success_response_serializer(UserPermissionExtensionSerializer(many=True), "获取成功", "AllPermissions"),
        }
    )
    @action(detail=False, methods=['get'], permission_classes=[SelfReadPermission])
    def all_permissions(self, request):
        """获取所有可分配权限 - 模式3A: 自定义Action"""
        # 获取所有激活状态的权限扩展
        permission_extensions = PermissionExtension.objects.filter(
            status='active'
        ).order_by('module', 'permission__name')

        # 使用序列化器序列化数据
        serializer = UserPermissionExtensionSerializer(permission_extensions, many=True)
        return self.success_response(serializer.data, "获取所有权限成功")

    @extend_schema(
        summary="用户登出",
        description="用户登出，清除客户端Token",
        responses={
            200: "登出成功",
        }
    )
    @action(detail=False, methods=['post'])
    def logout(self, request):
        """用户登出"""
        return self.success_response(
            None,
            "登出成功"
        )


class CustomTokenObtainPairView(TokenObtainPairView, ApiResponseMixin):
    """自定义Token获取视图 - 统一响应格式"""

    @extend_schema(
        summary="用户登录获取Token",
        description="使用用户名/邮箱和密码登录，获取JWT Token",
        responses={
            200: create_success_response_serializer(UserTokenSerializer, "登录成功", "TokenObtain"),
            401: UnauthorizedErrorResponseSerializer,
        }
    )
    def post(self, request, *args, **kwargs):
        # 首先验证用户凭据
        serializer = TokenObtainPairSerializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("登录信息无效", errors=serializer.errors, code=401)

        user = serializer.validated_data['user']

        # 更新最后登录时间
        user.last_login_at = timezone.now()
        user.save(update_fields=['last_login_at'])

        # 生成JWT Token
        refresh = RefreshToken.for_user(user)

        return self.success_response({
            'access': str(refresh.access_token),
            'refresh': str(refresh),
            'user': UserProfileSerializer(user).data
        }, "登录成功")


class CustomTokenRefreshView(TokenRefreshView, ApiResponseMixin):
    """自定义Token刷新视图 - 统一响应格式"""

    @extend_schema(
        summary="刷新Token",
        description="使用refresh token获取新的access token",
        responses={
            200: create_success_response_serializer(UserTokenSerializer, "刷新成功", "TokenRefresh"),
            401: UnauthorizedErrorResponseSerializer,
        }
    )
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        if response.status_code == 200:
            return self.success_response(response.data, "Token刷新成功")
        return self.error_response('Token刷新失败', response.data, response.status_code)
